home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
kcl.lha
/
cmpnew
/
cmpcatch.lsp
< prev
next >
Wrap
Lisp/Scheme
|
1987-06-03
|
4KB
|
108 lines
;;; CMPCATCH Catch, Unwind-protect, and Throw.
;;;
;; (c) Copyright Taiichi Yuasa and Masami Hagiya, 1984. All rights reserved.
;; Copying of this file is authorized to users who have executed the true and
;; proper "License Agreement for Kyoto Common LISP" with SIGLISP.
(in-package 'compiler)
(si:putprop 'catch 'c1catch 'c1special)
(si:putprop 'catch 'c2catch 'c2)
(si:putprop 'unwind-protect 'c1unwind-protect 'c1special)
(si:putprop 'unwind-protect 'c2unwind-protect 'c2)
(si:putprop 'throw 'c1throw 'c1special)
(si:putprop 'throw 'c2throw 'c2)
(defun c1catch (args &aux (info (make-info :sp-change t)) tag)
(when (endp args) (too-few-args 'catch 1 0))
(setq tag (c1expr (car args)))
(add-info info (cadr tag))
(setq args (c1progn (cdr args)))
(add-info info (cadr args))
(list 'catch info tag args))
(si:putprop 'push-catch-frame 'set-push-catch-frame 'set-loc)
(defun c2catch (tag body &aux (*vs* *vs*))
(let ((*value-to-go* '(push-catch-frame))) (c2expr* tag))
(wt-nl "if(nlj_active)")
(wt-nl "{nlj_active=FALSE;frs_pop();")
(unwind-exit 'fun-val 'jump)
(wt "}")
(wt-nl "else{")
(let ((*unwind-exit* (cons 'frame *unwind-exit*)))
(c2expr body))
(wt "}")
)
(defun set-push-catch-frame (loc)
(wt-nl "frs_push(FRS_CATCH," loc ");"))
(defun c1unwind-protect (args &aux (info (make-info :sp-change t)) form)
(when (endp args) (too-few-args 'unwind-protect 1 0))
(setq form (let ((*blocks* (cons 'lb *blocks*))
(*tags* (cons 'lb *tags*))
(*vars* (cons 'lb *vars*)))
(c1expr (car args))))
(add-info info (cadr form))
(setq args (c1progn (cdr args)))
(add-info info (cadr args))
(list 'unwind-protect info form args)
)
(defun c2unwind-protect (form body
&aux (*vs* *vs*) (loc (list 'vs (vs-push))))
(wt-nl "{object tag;frame_ptr fr;object p;bool active;")
(wt-nl "frs_push(FRS_PROTECT,Cnil);")
(wt-nl "if(nlj_active){tag=nlj_tag;fr=nlj_fr;active=TRUE;}")
(wt-nl "else{")
(let ((*value-to-go* 'top)) (c2expr* form))
(wt-nl "active=FALSE;}")
(wt-nl loc "=Cnil;")
(wt-nl "while(vs_base<vs_top)")
(wt-nl "{" loc "=MMcons(vs_top[-1]," loc ");vs_top--;}")
(wt-nl) (reset-top)
(wt-nl "nlj_active=FALSE;frs_pop();")
(let ((*value-to-go* 'trash)) (c2expr* body))
(wt-nl "vs_base=vs_top=base+" *vs* ";")
(base-used)
(wt-nl "for(p= " loc ";!endp(p);p=MMcdr(p))vs_push(MMcar(p));")
(wt-nl "if(active)unwind(fr,tag);else{")
(unwind-exit 'fun-val)
(wt "}}")
)
(defun c1throw (args &aux (info (make-info)) tag)
(when (or (endp args) (endp (cdr args)))
(too-few-args 'throw 2 (length args)))
(unless (endp (cddr args))
(too-many-args 'throw 2 (length args)))
(setq tag (c1expr (car args)))
(add-info info (cadr tag))
(setq args (c1expr (cadr args)))
(add-info info (cadr args))
(list 'throw info tag args)
)
(defun c2throw (tag val &aux (*vs* *vs*) loc)
(wt-nl "{frame_ptr fr;")
(case (car tag)
(LOCATION (setq loc (caddr tag)))
(VAR (let ((var (caaddr tag)))
(declare (object var))
(case (var-kind var)
(LEXICAL (setq loc (list 'vs (var-ref var))))
(REPLACED (setq loc (var-loc var)))
(t (setq loc (list 'vs (vs-push)))
(wt-nl loc "= ") (wt-var var nil) (wt ";")))))
(t (setq loc (list 'vs (vs-push)))
(let ((*value-to-go* loc)) (c2expr* tag))))
(wt-nl "fr=frs_sch_catch(" loc ");")
(wt-nl "if(fr==NULL) FEerror(\"The tag ~s is undefined.\",1," loc ");")
(let ((*value-to-go* 'top)) (c2expr* val))
(wt-nl "unwind(fr," loc ");}")
)